using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using CGF;

[AddComponentMenu("CGFramework/CLine")]
public class CLine : Image
{
    public float _lineSize = 2f;
    public float _cornerSize = 2f;
    public Vector2[] _points = new Vector2[2];

    [SerializeField] private bool _useDashedLine = false;
    [SerializeField] private float _dashLength = 10f;
    [SerializeField] private float _gapLength = 5f;

    private readonly List<UIVertex> _vertices = new List<UIVertex>();
    private readonly List<int> _triangles = new List<int>();

    /// <summary>
    /// 折线的端点位置数组（本地坐标）
    /// </summary>
    public Vector2[] Points
    {
        get => _points;
        set
        {
            if (_points != value)
            {
                _points = value;
                ReDraw();
            }
        }
    }

    /// <summary>
    /// 线的宽度
    /// </summary>
    public float LineSize
    {
        get => _lineSize;
        set
        {
            if (!Mathf.Approximately(_lineSize, value))
            {
                _lineSize = Mathf.Max(0, value);
                ReDraw();
            }
        }
    }
    
    /// <summary>
    /// 线的宽度
    /// </summary>
    public float CornerSize
    {
        get => _cornerSize;
        set
        {
            if (!Mathf.Approximately(_cornerSize, value))
            {
                _cornerSize = Mathf.Max(0, value);
                ReDraw();
            }
        }
    }

    /// <summary>
    /// 是否使用虚线形式绘制
    /// </summary>
    public bool UseDashedLine
    {
        get => _useDashedLine;
        set
        {
            if (_useDashedLine != value)
            {
                _useDashedLine = value;
                ReDraw();
            }
        }
    }

    /// <summary>
    /// 虚线中实线部分的长度
    /// </summary>
    public float DashLength
    {
        get => _dashLength;
        set
        {
            if (!Mathf.Approximately(_dashLength, value))
            {
                _dashLength = Mathf.Max(0.1f, value);
                ReDraw();
            }
        }
    }

    /// <summary>
    /// 虚线中间隔的长度
    /// </summary>
    public float GapLength
    {
        get => _gapLength;
        set
        {
            if (!Mathf.Approximately(_gapLength, value))
            {
                _gapLength = Mathf.Max(0.1f, value);
                ReDraw();
            }
        }
    }

    public void ReDraw()
    {
        SetVerticesDirty();
        Show();
    }

    private async void Show()
    {
        if (!Application.isPlaying) return;
        await CTask.Wait(0.01f);
        if (!Application.isPlaying) return;
        try
        {
            if (!gameObject.activeSelf) gameObject.SetActive(true);
        }
        catch { }
    }

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();

        if (_points == null || _points.Length < 2 || _lineSize <= 0)
        {
            base.OnPopulateMesh(vh);
            return;
        }

        _vertices.Clear();
        _triangles.Clear();

        if (_useDashedLine)
        {
            GenerateDashedLineMesh();
        }
        else
        {
            GenerateSolidLineMesh();
        }

        for (int i = 0; i < _vertices.Count; i++)
        {
            vh.AddVert(_vertices[i]);
        }

        for (int i = 0; i < _triangles.Count; i += 3)
        {
            vh.AddTriangle(_triangles[i], _triangles[i + 1], _triangles[i + 2]);
        }
    }

    /// <summary>
    /// 生成实线网格
    /// </summary>
    private void GenerateSolidLineMesh()
    {
        // 生成第一个端点的完整圆形帽
        if (_points.Length > 0)
        {
            GenerateFullCap(_points[0]);
        }

        // 生成中间线段
        for (int i = 0; i < _points.Length - 1; i++)
        {
            GenerateSegment(_points[i], _points[i + 1]);
        }

        // 生成连接处的圆形（在折点处）
        for (int i = 1; i < _points.Length - 1; i++)
        {
            GenerateJointCircle(_points[i]);
        }

        // 生成最后一个端点的完整圆形帽
        if (_points.Length > 1)
        {
            GenerateFullCap(_points[_points.Length - 1]);
        }
    }

    /// <summary>
    /// 生成虚线网格
    /// </summary>
    private void GenerateDashedLineMesh()
    {
        // 虚线模式下不生成端点帽和连接圆，只生成线段
        for (int i = 0; i < _points.Length - 1; i++)
        {
            GenerateDashedSegment(_points[i], _points[i + 1]);
        }
    }

    /// <summary>
    /// 生成折线连接处的圆形（以连接点为中心）
    /// </summary>
    private void GenerateJointCircle(Vector2 jointPoint)
    {
        int segments = 16;
        int baseIndex = _vertices.Count;

        // 圆心顶点（就是连接点本身）
        UIVertex centerVertex = CreateVertex(jointPoint, color);
        _vertices.Add(centerVertex);

        // 生成完整的圆形
        for (int i = 0; i <= segments; i++)
        {
            float angle = 2f * Mathf.PI * i / segments;
            Vector2 offset = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * _cornerSize * 0.5f;
            Vector2 vertexPos = jointPoint + offset;

            UIVertex vertex = CreateVertex(vertexPos, color);
            _vertices.Add(vertex);

            // 添加三角形扇面
            if (i > 0)
            {
                _triangles.Add(baseIndex);
                _triangles.Add(baseIndex + i);
                _triangles.Add(baseIndex + i + 1);
            }
        }
    }

    /// <summary>
    /// 生成完整圆形端点帽（简化版本，与连接圆使用相同逻辑）
    /// </summary>
    private void GenerateFullCap(Vector2 point)
    {
        int segments = 16;
        int baseIndex = _vertices.Count;

        // 圆心顶点
        UIVertex centerVertex = CreateVertex(point, color);
        _vertices.Add(centerVertex);

        // 生成完整的圆形
        for (int i = 0; i <= segments; i++)
        {
            float angle = 2f * Mathf.PI * i / segments;
            Vector2 offset = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * _cornerSize * 0.5f;
            Vector2 vertexPos = point + offset;

            UIVertex vertex = CreateVertex(vertexPos, color);
            _vertices.Add(vertex);

            // 添加三角形扇面
            if (i > 0)
            {
                _triangles.Add(baseIndex);
                _triangles.Add(baseIndex + i);
                _triangles.Add(baseIndex + i + 1);
            }
        }
    }

    /// <summary>
    /// 生成虚线线段段
    /// </summary>
    private void GenerateDashedSegment(Vector2 start, Vector2 end)
    {
        Vector2 direction = (end - start).normalized;
        float segmentLength = Vector2.Distance(start, end);
        float totalPatternLength = _dashLength + _gapLength;

        if (totalPatternLength <= 0) return;

        int patternCount = Mathf.FloorToInt(segmentLength / totalPatternLength);
        float remainingLength = segmentLength;

        for (int i = 0; i <= patternCount; i++)
        {
            float currentDashLength = Mathf.Min(_dashLength, remainingLength);

            if (currentDashLength > 0)
            {
                Vector2 dashStart = start + direction * (i * totalPatternLength);
                Vector2 dashEnd = dashStart + direction * currentDashLength;

                GenerateSegment(dashStart, dashEnd);
            }

            remainingLength -= totalPatternLength;
        }
    }

    /// <summary>
    /// 生成一个线段段
    /// </summary>
    private void GenerateSegment(Vector2 start, Vector2 end)
    {
        Vector2 direction = (end - start).normalized;
        Vector2 perpendicular = new Vector2(-direction.y, direction.x) * _lineSize * 0.5f;

        int baseIndex = _vertices.Count;

        UIVertex vertexA = CreateVertex(start - perpendicular, color);
        UIVertex vertexB = CreateVertex(start + perpendicular, color);
        UIVertex vertexC = CreateVertex(end + perpendicular, color);
        UIVertex vertexD = CreateVertex(end - perpendicular, color);

        _vertices.Add(vertexA);
        _vertices.Add(vertexB);
        _vertices.Add(vertexC);
        _vertices.Add(vertexD);

        _triangles.Add(baseIndex);
        _triangles.Add(baseIndex + 1);
        _triangles.Add(baseIndex + 2);

        _triangles.Add(baseIndex);
        _triangles.Add(baseIndex + 2);
        _triangles.Add(baseIndex + 3);
    }

    /// <summary>
    /// 创建顶点数据
    /// </summary>
    private UIVertex CreateVertex(Vector2 position, Color vertexColor)
    {
        return new UIVertex
        {
            position = position,
            color = vertexColor,
            uv0 = Vector2.zero
        };
    }

    /// <summary>
    /// 添加一个端点
    /// </summary>
    public void AddPoint(Vector2 point)
    {
        List<Vector2> pointsList = new List<Vector2>(_points);
        pointsList.Add(point);
        Points = pointsList.ToArray();
    }

    /// <summary>
    /// 清空所有端点
    /// </summary>
    public void ClearPoints()
    {
        Points = new Vector2[0];
    }

    /// <summary>
    /// 在指定索引处插入端点
    /// </summary>
    public void InsertPoint(int index, Vector2 point)
    {
        if (index < 0 || index > _points.Length) return;

        List<Vector2> pointsList = new List<Vector2>(_points);
        pointsList.Insert(index, point);
        Points = pointsList.ToArray();
    }

    /// <summary>
    /// 移除指定索引处的端点
    /// </summary>
    public void RemovePoint(int index)
    {
        if (index < 0 || index >= _points.Length) return;

        List<Vector2> pointsList = new List<Vector2>(_points);
        pointsList.RemoveAt(index);
        Points = pointsList.ToArray();
    }

#if UNITY_EDITOR
    protected override void OnValidate()
    {
        base.OnValidate();
        if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
        {
            ReDraw();
        }
    }
    
    [UnityEditor.MenuItem("CGFramework/创建 CLine")]
    [UnityEditor.MenuItem("GameObject/CGFramework/创建 CLine", priority = -2200)]
    static void Create()
    {
        GameObject go = new GameObject("CLine");
        go.layer = LayerMask.NameToLayer("UI");
        go.transform.SetParent(UnityEditor.Selection.activeGameObject.transform, false);
        go.AddComponent<CLine>();
        UnityEditor.EditorUtility.SetDirty(go);
    }
#endif
}
